#include "GameObject.h"


using namespace std;

///////////////////////////////////////////////////////////////
//Statics
///////////////////////////////////////////////////////////////

std::vector<GameObject*> GameObject::_gameObjectsInScene;

//Update
void GameObject::UpdateScene(float time)
{
	vector<GameObject*>::iterator itCurrent = _gameObjectsInScene.begin();
	vector<GameObject*>::iterator itEnd = _gameObjectsInScene.end();

	while(itCurrent != itEnd)
	{
		(*itCurrent)->Update(time);
		++itCurrent;
	}
}

//Render
void GameObject::RenderScene(Matrix4 view, Matrix4 proj)
{
	vector<GameObject*>::iterator itCurrent = _gameObjectsInScene.begin();
	vector<GameObject*>::iterator itEnd = _gameObjectsInScene.end();

	while(itCurrent != itEnd)
	{
		if((*itCurrent)->_parent != NULL)
		{
			++itCurrent;
			continue;
		}

		(*itCurrent)->Render(view, proj);
		++itCurrent;
	}
}


void GameObject::DeleteScene()
{
	vector<GameObject*>::iterator itCurrent = _gameObjectsInScene.begin();
	vector<GameObject*>::iterator itEnd = _gameObjectsInScene.end();

	while(itCurrent != itEnd)
	{
		GameObject* current = *itCurrent;
		
		if(current->_parent != NULL)
		{
			++itCurrent;
			continue;
		}
		
		delete(current);
		++itCurrent;
	}
	_gameObjectsInScene.clear();
}


///////////////////////////////////////////////////////////////
//Constructor & Destructor
///////////////////////////////////////////////////////////////

GameObject::GameObject()
{
	_name = "New Game Object";
	_transform = new Transform();

	_gameObjectsInScene.push_back(this);
	_parent = NULL;

}

GameObject::GameObject(string name): _name(name)
{
	_transform = new Transform();
	_gameObjectsInScene.push_back(this);
	_parent = NULL;
	
}

GameObject::~GameObject()
{
	if(_parent != NULL)
		_parent = NULL;

	if(_transform != NULL)
		delete(_transform);
	
	//Clear Childs
	vector<GameObject*>::iterator itGOCurrent = _childs.begin();
	vector<GameObject*>::iterator itGOEnd = _childs.end();

	while(itGOCurrent != itGOEnd)
	{
		GameObject* go = *itGOCurrent;
		delete(go);
		++itGOCurrent;
	}
	
	_childs.clear();

	//Clear Components
	vector<Component*>::iterator itCurrent = _components.begin();
	vector<Component*>::iterator itEnd = _components.end();

	int size = _components.size();
	while(itCurrent != itEnd)
	{
		
		Component* comp = *itCurrent;
		delete(comp);
		++itCurrent;
	}
	
	_components.clear();
}


///////////////////////////////////////////////////////////////
//Runtime
///////////////////////////////////////////////////////////////

void GameObject::Update(float time)
{

}


void GameObject::Render(Matrix4 view, Matrix4 proj)
{
	if(_transform == NULL)
		return;

	Matrix4 posMat;
	posMat.Identity();
	posMat.W.x = -_transform->position.x;
	posMat.W.y = _transform->position.y;
	posMat.W.z = _transform->position.z;

	view = MultiplyMatrix(view, posMat);

	view = MultiplyMatrix(view, RotateX(_transform->orientation.x));
	view = MultiplyMatrix(view, RotateY(_transform->orientation.y));
	view = MultiplyMatrix(view, RotateZ(_transform->orientation.z));
	view = MultiplyMatrix(view, RotateZ(_transform->orientation.z));

	Matrix4 scaleMat;
	scaleMat.Identity();
	scaleMat.X.x = _transform->scale.x;
	scaleMat.Y.y = _transform->scale.y;
	scaleMat.Z.z = _transform->scale.z;

	view = MultiplyMatrix(view, scaleMat);

	vector<Component*>::iterator it = _components.begin();
	while(it != _components.end())
	{
		Component* comp = *it;
		comp->Render(view, proj);
		++it;
	}
	
	//Render Childs
	int nbChilds = _childs.size();
	for(int i = 0; i < nbChilds; ++i)
	{
		_childs[i]->Render(view, proj);
	}
	
}
